<?php
/**
 * Created by PhpStorm.
 * User: aron
 * Date: 2019/5/8
 * Time: 1:59 PM
 */

define("DEBUG_MODE_SHOW_ERROR", FALSE);
include_once "../../Util/DebugUtil/DebugUtil.php";


class TestClass {
    /**
     * 重写__call方法，调用对象不存在的方法会调用该方法
     * @param $name 方法名称
     * @param $arguments 参数列表是数组类型
     */
    public function __call($name, $arguments)
    {
        echo "TestClass __call 【 \$name => $name \$arguments => $arguments 】";
        yt_debug_print_break_line();
        if (is_array($arguments)) {
            echo "\$arguments => ";
            yt_debug_print_break_line();
            DebugUtil::printArray($arguments);
        }
    }

    /**
     * 重写__callStatic方法，调用类不存在的方法会调用该方法
     * @param $name
     * @param $arguments
     */
    public static function __callStatic($name, $arguments)
    {
        echo "TestClass __callStatic 【 \$name => $name \$arguments => $arguments 】";
        yt_debug_print_break_line();
    }

}

// Demo
if (false){

    $obj = new TestClass();
    $obj->undefinedMethod("param1");
    $obj->undefinedMethod("param1", "param2");
    $obj->yndefinedMethod2("params1", array("param2", "param3"));

    DebugUtil::printDebugSeperator();

    TestClass::undefinedStaticMethod("param1");
    TestClass::undefinedMethod("param1", "param2");
    TestClass::yndefinedMethod2("params1", array("param2", "param3"));
}


/***************** __call方法的高级应用 ********************/
DebugUtil::printDebugSeperator("__call方法的高级应用");

interface IBaseSqlOperation
{
    public function field();

    public function where();

    public function order();

    public function limit();

    public function group();

    public function having();
}

abstract class BaseSqlOperation
{
    abstract public function field();

    abstract public function where();

    abstract public function order();

    abstract public function limit();

    abstract public function group();

    abstract public function having();
}

class MySqlOperation  /*extends BaseSqlOperation*/  /*implements BaseSqlOperation*/ {

    private $sql = array(
        "db_name" => "",
        "field" => "",
        "where" => "",
        "order" => "",
        "limit" => "",
        "group" => "",
        "having" => "",
    );

    /**
     * 重写__call方法
     * @param $name
     * @param $arguments
     */
    public function __call($name, $arguments)
    {
        echo "MySqlOperation __call 【 \$name => $name \$arguments => $arguments 】";
        yt_debug_print_break_line();
        if (is_array($arguments)) {
            DebugUtil::printArray($arguments);
        }
        yt_debug_print_break_line();


        // 添加数据到数组中
        if (array_key_exists($name, $this->sql)) {
            $this->sql[$name] = $arguments;
        }

        // 返回当前对象，能够支持链式调用
        return $this;
    }

    public function selectSQL()
    {
        return "SELECT {$this->_field()} FROM {$this->_dbName()} WHERE {$this->_where()} LIMIT {$this->_limit()}}";
    }

    /***************** Helper ********************/
    private function _field()
    {
        $fileds = $this->sql['field'];
        if (empty($fileds)) {
            return "*";
        }
        if (is_array($fileds)){
            return implode("," ,$fileds);
        } else {
            return $fileds;
        }
    }

    private function _where()
    {
        $where = $this->sql['where'];
        if (empty($where)) {
            return "1=1";
        }
        if (is_array($where)) {
            return $where[0];
        } else {
            return $where;
        }
    }

    private function _limit()
    {
        $limit = $this->sql['limit'];
        if (empty($limit)) {
            return "10000";
        }
        if (is_array($limit)) {
            return $limit[0];
        } else {
            return $limit;
        }
    }

    private function _dbName()
    {
        $db_name = $this->sql['db_name'];
        if (empty($db_name)) {
            return __CLASS__;
        }
        if (is_array($db_name)) {
            return $db_name[0];
        } else {
            return $db_name;
        }
    }
}

// Demo
if (true) {
    $mysqlOpe = new MySqlOperation();
    $mysqlOpe->field("id", "name");
    $mysqlOpe->where("id = 100");
    $mysqlOpe->order("id");
    $mysqlOpe->limit(10);

    $sql = $mysqlOpe->selectSQL();
    echo "\$sql = $sql";
    // Output:
    // $sql = SELECT id,name FROM MySqlOperation WHERE id = 100 LIMIT 10}
    yt_debug_print_break_line();


    DebugUtil::printDebugSeperator("链式调用");
    $mysqlOpe = new MySqlOperation();
    $mysqlOpe->field("id", "name", "age")->where("id = 100")->order("id")->db_name("User_DB");
    echo "\$sql = {$mysqlOpe->selectSQL()}";
    // Output:
    // $sql = SELECT id,name,age FROM User_DB WHERE id = 100 LIMIT 10000}
    yt_debug_print_break_line();
}


/***************** 自动加载类 ********************/
yt_debug_print_break_line();
DebugUtil::printDebugSeperator("自动加载类");
function __autoload($className) {
    echo "__autoload 【 \$className => $className 】";
    // 导入需要使用到的类，需要加上路径信息
    include "./Class/{$className}.class.php";
}

// 调用__autoload方法
$obj = new Student();


yt_debug_print_break_line();
DebugUtil::printDebugSeperator("END");
